package ch.zbw.pra.sysventory.network.server;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

import ch.zbw.pra.sysventory.domain.dbconnector.IDBConnector;
import ch.zbw.pra.sysventory.domain.util.MyLogger;

public class TCPServer implements Runnable {

	private static final org.slf4j.Logger log = org.slf4j.LoggerFactory
			.getLogger(TCPServer.class);

	private ServerSocket server;
	private int port = 7777;
	private boolean isStopped = false;
	private boolean isScanning = false;
	private IDBConnector connector;
	private ArrayList<ConnectionHandler> handlers;

	public TCPServer(int port, IDBConnector connector) {
		this.port = port;
		this.connector = connector;
		this.handlers = new ArrayList<ConnectionHandler>();
	}

	public void run() {

		openServerSocket();
		while (!isStopped()) {
			Socket clientSocket = null;
			try {
				clientSocket = this.server.accept();
				InetAddress clientHost = clientSocket.getInetAddress();
				MyLogger.logDebug(log, "Neuer Client hat sich angemeldet: IP=" + clientHost);
			} catch (IOException e) {
				if (isStopped()) {
					MyLogger.logDebug(log, "Server Stopped.");
					return;
				}
				MyLogger.logError(log, "Error accepting client connection" + e.toString());
			}
			ConnectionHandler handler = new ConnectionHandler(clientSocket, this.connector);
			// damit wird immer gescannt
			// handler.setScanning(this.isScanning);
			this.handlers.add(handler);
		}
		MyLogger.logDebug(log, "Server Stopped.");
	}

	private synchronized boolean isStopped() {
		return this.isStopped;
	}

	public synchronized void stop() {
		this.isStopped = true;
		try {
			this.server.close();
		} catch (IOException e) {
			MyLogger.logError(log, e.toString());
		}
	}

	private void openServerSocket() {
		try {
			this.server = new ServerSocket(this.port);
			MyLogger.logDebug(log,
					"Server connected on: " + InetAddress.getLocalHost().getCanonicalHostName()
							+ ":" + this.server.getLocalPort());
		} catch (IOException e) {
			MyLogger.logError(log, e.toString());
		}
	}

	public synchronized void setScanning(boolean isScanning) {
		this.isScanning = isScanning;
		for (ConnectionHandler connHandler : this.handlers) {
			connHandler.setScanning(this.isScanning);
		}
	}

	public synchronized void closeHandlers() {
		for (ConnectionHandler connHandler : this.handlers) {
			connHandler.closeSocket();
		}
	}

	public synchronized boolean isScanFinished() {
		// for (ConnectionHandler connHandler : this.handlers) {
		// while (!connHandler.isScanFinished()) {
		// }
		// }
		return true;
	}

}
